#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define NUM_CHILDREN 3
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 30

typedef struct {
    Window win;
    Window button;
    int index;
} ChildWindow;

ChildWindow children[NUM_CHILDREN];
Display *display;
Window root;
Window parent;

void create_button(ChildWindow *child, int x, int y) {
    // 创建按钮窗口
    child->button = XCreateSimpleWindow(display, child->win, 
                                       x, y, BUTTON_WIDTH, BUTTON_HEIGHT, 
                                       1, BlackPixel(display, 0), 
                                       WhitePixel(display, 0));
    
    // 选择输入事件
    XSelectInput(display, child->button, ExposureMask | ButtonPressMask);
    
    // 设置按钮标题
    char title[32];
    snprintf(title, sizeof(title), "Btn %d", child->index);
    XStoreName(display, child->button, title);
    
    // 映射按钮窗口
    XMapWindow(display, child->button);
}

void draw_button(Window win, const char *text) {
    XGCValues values;
    GC gc = XCreateGC(display, win, 0, &values);
    
    // 绘制按钮背景
    XSetForeground(display, gc, WhitePixel(display, 0));
    XFillRectangle(display, win, gc, 0, 0, BUTTON_WIDTH, BUTTON_HEIGHT);
    
    // 绘制边框
    XSetForeground(display, gc, BlackPixel(display, 0));
    XDrawRectangle(display, win, gc, 0, 0, BUTTON_WIDTH-1, BUTTON_HEIGHT-1);
    
    // 绘制文本
    int text_x = (BUTTON_WIDTH - XTextWidth(XLoadQueryFont(display, "fixed"), text, strlen(text))) / 2;
    int text_y = (BUTTON_HEIGHT + 10) / 2;  // 10是字体大致高度
    XDrawString(display, win, gc, text_x, text_y, text, strlen(text));
    
    XFreeGC(display, gc);
}

void handle_button_press(Window win) {
    // 查找是哪个子窗口的按钮被点击了
    for (int i = 0; i < NUM_CHILDREN; i++) {
        if (win == children[i].button) {
            printf("Button clicked on child window %d\n", children[i].index);
            break;
        }
    }
}

void handle_expose(Window win) {
    // 如果是按钮窗口的Expose事件，重绘按钮
    for (int i = 0; i < NUM_CHILDREN; i++) {
        if (win == children[i].button) {
            char title[32];
            snprintf(title, sizeof(title), "Btn %d", children[i].index);
            draw_button(win, title);
            break;
        }
    }
}

int main() {
    display = XOpenDisplay(NULL);
    if (!display) {
        fprintf(stderr, "Cannot open display\n");
        exit(1);
    }
    
    root = DefaultRootWindow(display);
    int screen = DefaultScreen(display);
    
    // 创建父窗口（合成容器）
    parent = XCreateSimpleWindow(display, root, 100, 100, 400, 300, 1, 
                               BlackPixel(display, screen), 
                               WhitePixel(display, screen));
    XSelectInput(display, parent, ExposureMask | SubstructureNotifyMask);
    XMapWindow(display, parent);
    
    // 创建多个子窗口
    for (int i = 0; i < NUM_CHILDREN; i++) {
        children[i].win = XCreateSimpleWindow(display, root, 0, 0, 200, 150, 1, 
                                           BlackPixel(display, screen), 
                                           rand() % 0xFFFFFF);
        children[i].index = i;
        
        // 选择输入事件
        XSelectInput(display, children[i].win, ExposureMask);
        
        // 创建按钮
        create_button(&children[i], 60, 60);  // 按钮在子窗口中的位置
        
        XMapWindow(display, children[i].win);
    }
    
    // 等待窗口初始化完成
    XSync(display, False);
    sleep(1);
    
    // 将子窗口重新挂载到父窗口下
    for (int i = 0; i < NUM_CHILDREN; i++) {
        XReparentWindow(display, children[i].win, parent, 
                       50 + (i % 2) * 100,  // X位置
                       50 + (i / 2) * 100); // Y位置
    }
    
    // 事件循环
    XEvent event;
    while (1) {
        XNextEvent(display, &event);
        
        switch (event.type) {
            case Expose:
                handle_expose(event.xexpose.window);
                break;
                
            case ButtonPress:
                handle_button_press(event.xbutton.window);
                break;
                
            default:
                break;
        }
    }
    
    XCloseDisplay(display);
    return 0;
}
